#ifndef SKELETALBASE_H
#define SKELETALBASE_H
#include "math/Matrix4X3.h"
#include "math/Quaternion.h"
#include "math/Vector3D.h"

#include "cocos2d.h"

#ifndef DWORD
#define DWORD unsigned long
#endif

struct RotateKey
{
	DWORD          _time;
	Quaternion _quaternion;
};

struct PositionKey
{
	DWORD     	_time;
	Vector3D	_pos;
	Vector3D	_posInterpolation;
};

struct ScaleKey
{
	DWORD	    _time;
	Vector3D	_scale;
	Vector3D	_scaleInterpolation;
};

struct MatrixKey
{
	DWORD	   _time;
	Matrix4X3 _matrix;
	Matrix4X3 _matInterpolation;
};

struct Frame
{
	Frame()
	{
		//_pName        = NULL;
		//_pFrameMeshes = NULL;
		_pParent      = NULL;
		_pSibling     = NULL;
		_pChild       = NULL;
		_pSprBone     = NULL;
	}
	~Frame()
	{
        
		//if(NULL != _pName)
		//{
		//	delete _pName;
		//}
        
		/*
        if(NULL != _pFrameMeshes)
        {
            delete   _pFrameMeshes;
        }
        
        */
        
		if(NULL != _pChild)
		{
			delete   _pChild;
		}
        
		if(NULL != _pSibling)
		{
			delete   _pSibling;
		}
        
		// parent不用释放，都包含在孩子里了
	}
    
    void AddChild(Frame *pChild)
    {
        if(NULL == _pChild)
        {
            _pChild = pChild;
            return;
        }
        
        Frame *pNext = _pChild;
        
        while(pNext->_pSibling != NULL)
        {
            pNext = pNext->_pSibling;
        }
        
        pNext->_pSibling = pChild;
    }
    
	//char       *_pName;
    
	// 这个暂时只有parent拥有
    
	//FrameMeshList  *_pFrameMeshes;
    
	// 这些矩阵是FRAME的精要
    
	cocos2d::CCSprite *_pSprBone;
    
	Matrix4X3  _matCombined;    // 合成矩阵，每一个骨骼最终的变换矩阵
	Matrix4X3  _matTransformed; // 当前变换矩阵
	Matrix4X3  _matOriginal;    // 原始矩阵
    
	// 二叉树
	Frame      *_pParent;		
	Frame      *_pSibling;
	Frame      *_pChild;
};

//////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 结构体：Animation
//
// 功能：一个动作，包含一系列的键，用来合成矩阵和进行插值
//
// 主要功能介绍：
//
//		   一，动作的结构，动作也是一个链表的结构，每一个动作对应一块骨头，一个链表连起一个模型
//     这个模型就是当前的整个画面
//
//         二，与Frame的关系，每一个 Animation 对应一个 Frame ，当键值更新时，可以直接反应到相应的
//     Frame 上边而 Frame 和 Animation 通过(_pFrameName)来进行关联。
//
//         三，循环标记(_bLoop)用来标记是否使用循环来播放动画
//
//         四，(_bLinear) 保留，未使用
//
//////////////////////////////////////////////////////////////////////////////////////////////////////

struct Animation
{
	Animation()
	{
		//_pName         = NULL;
		_pFrame        = NULL;
		//_pFrameName    = NULL;
		_pNext         = NULL;
		_pRotateKeys   = NULL;
		_pPositionKeys = NULL;
		_pScaleKeys    = NULL;
		//_pMatrixKeys   = NULL;
        
		_bLoop         = false;
		//_bLinear       = false;
        
		_nRotateKeys   = 0;
		_nPositionKeys = 0;
		_nScaleKeys    = 0;
		//_nMatrixKeys    = 0;
		_bUseRotTime = false;
		_bUsePosTime = false;
		_curRotTime       = 0;
		_curPosTime       = 0;
        
	}
	~Animation()
	{		
		//delete [] _pName;		
		//delete [] _pFrameName;			
		delete [] _pRotateKeys;		
		delete [] _pPositionKeys;
		delete [] _pScaleKeys;
		//delete [] _pMatrixKeys;
		delete _pNext;
	}
    
	//char        *_pName;			// 动画名，一般为空。
	Animation   *_pNext;			// 链表
    
	
	//char        *_pFrameName;		// 此动画关联的帧名，用来关联帧
	Frame       *_pFrame;			// 关联的帧，不负责释放
	
	
	RotateKey   *_pRotateKeys;
	DWORD        _nRotateKeys;
    
	PositionKey *_pPositionKeys;
	DWORD        _nPositionKeys;
    
	ScaleKey    *_pScaleKeys;
	DWORD        _nScaleKeys;
	
	/*
     MatrixKey     *_pMatrixKeys;
     unsigned long  _nMatrixKeys;
     */
	bool         _bLoop;			// 标记是否循环
	//bool         _bLinear;
    
	bool         _bUseRotTime;
	bool         _bUsePosTime;
    
	float        _curRotTime;
	float        _curPosTime;
    
    
};


//////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 结构体：AnimationSet
//
// 功能：动画集用于存储一组动作，并进行管理
//
// 主要功能介绍：
//
//		   一，动作集的结构，动画集为链表结构以方便查找
//
//         二，_length，此成员标识此动画的最大长度，即Animation中，所有键的_time成员的最大值
//
//////////////////////////////////////////////////////////////////////////////////////////////////////

const int ANIMATIONSET_NAME_MAX = 128;
struct AnimationSet
{
	AnimationSet()
	{
		_pName  = NULL;
		_pNext  = NULL;
		_pAnim  = NULL;
		_length = 0;
	}
	~AnimationSet()
	{
        
		delete [] _pName;	
		delete _pAnim;		
		delete _pNext;
        
	}
    
	char         *_pName;
    
	AnimationSet *_pNext;
	Animation    *_pAnim;
    
	unsigned long _length;		// 一个动画的长度
};

#endif
